<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace User\Controller;

use Admin\Controller\AdminActionController;
use Admin\Data\Common;
use Doctrine\ORM\EntityManager;
use Goods\Entity\GoodsClass;
use User\Entity\IntegralLog;
use User\Entity\IntegralRule;
use User\Entity\IntegralType;
use User\Entity\User;
use User\Form\EditUserIntegralForm;
use User\Form\IntegralRuleForm;
use User\Form\IntegralTypeForm;
use User\Form\SearchIntegralLogForm;
use User\Service\IntegralLogManager;
use User\Service\IntegralRuleManager;
use User\Service\IntegralTypeManager;
use User\Service\UserManager;
use Laminas\Mvc\I18n\Translator;

class IntegralController extends AdminActionController
{
    private $translator;
    private $entityManager;
    private $integralTypeManager;
    private $integralLogManager;
    private $userManager;
    private $integralRuleManager;

    public function __construct(
        Translator      $translator,
        EntityManager   $entityManager,
        IntegralTypeManager $integralTypeManager,
        IntegralLogManager $integralLogManager,
        UserManager     $userManager,
        IntegralRuleManager $integralRuleManager
    )
    {
        $this->translator           = $translator;
        $this->entityManager        = $entityManager;
        $this->integralTypeManager  = $integralTypeManager;
        $this->integralLogManager   = $integralLogManager;
        $this->userManager          = $userManager;
        $this->integralRuleManager  = $integralRuleManager;
    }

    /**
     * 积分类型列表
     * @return array|\Laminas\View\Model\ViewModel
     */
    public function indexAction()
    {
        $integralTypeList = $this->entityManager->getRepository(IntegralType::class)->findBy([], ['integralTypeId' => 'ASC']);

        return ['integralTypeList' => $integralTypeList];
    }

    /**
     * 编辑积分类型
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function editIntegralTypeAction()
    {
        $integralTypeId = (int) $this->params()->fromRoute('id', -1);
        $integralTypeInfo = $this->entityManager->getRepository(IntegralType::class)->findOneByIntegralTypeId($integralTypeId);
        if($integralTypeInfo === null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该积分类型不存在!'));
            return $this->redirect()->toRoute('user-integral');
        }

        $form = new IntegralTypeForm($integralTypeInfo);

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $this->integralTypeManager->editIntegralType($data, $integralTypeInfo);
                $this->createConfig()->createIntegral();

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('积分类型 %s 编辑成功!'), $integralTypeInfo->getIntegralTypeName()), $this->translator->translate('积分'));

                return $this->redirect()->toRoute('user-integral');
            }
        } else {
            $form->setData($integralTypeInfo->valuesArray());
        }

        return ['form' => $form, 'integralTypeInfo' => $integralTypeInfo];
    }

    /**
     * 规则列表
     * @return array
     */
    public function integralRuleAction()
    {
        $integralRule = $this->entityManager->getRepository(IntegralRule::class)->findBy([], ['integralRuleId' => 'DESC']);

        return ['integralRule' => $integralRule];
    }

    /**
     * 添加规则
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function addIntegralRuleAction()
    {
        //商品分类
        $goodsClass = $this->entityManager->getRepository(GoodsClass::class)->findBy([], ['classTopId' => 'ASC', 'classSort' => 'ASC']);
        $classList  = Common::classOptions($goodsClass);
        //商品品牌
        $brandList  = $this->goodsPlugin()->goodsBrandOptions('', false);

        $form = new IntegralRuleForm();
        $form->get('integralRuleType')->setValueOptions(['goodsBuy' => $this->translator->translate('商品购买'), 'userRegister' => $this->translator->translate('会员注册')]);
        $form->get('integralTypeId')->setValueOptions(Common::integralType($this->translator));
        $form->get('integralRuleUserType')->setValueOptions(['allUser' => $this->translator->translate('所有客户'), 'userGroup' => $this->translator->translate('客户分组')]);
        $form->get('userGroup')->setValueOptions($this->userPlugin()->userGroupOptions('', false));
        $form->get('integralRuleGoodsType')->setValueOptions(['allGoods' => $this->translator->translate('所有商品'), 'goodsClass' => $this->translator->translate('商品分类'), 'goodsBrand' => $this->translator->translate('商品品牌')]);
        $form->get('goodsBrand')->setValueOptions($brandList);
        $form->get('goodsClass')->setValueOptions($this->goodsPlugin()->classValueArray($goodsClass));

        if($this->getRequest()->isPost()) {
            $postData = $this->params()->fromPost();
            $form->setData($postData);
            if ($form->isValid()) {
                $data = $form->getData();

                if(!empty($data['integralRuleStartTime']))  $data['integralRuleStartTime']  = strtotime($data['integralRuleStartTime']);
                if(!empty($data['integralRuleEndTime']))    $data['integralRuleEndTime']    = strtotime($data['integralRuleEndTime']);
                $data['integralRuleBody']       = serialize((!in_array($data['integralRuleType'], ['userRegister']) ? $postData[$data['integralRuleType']] : []));
                $data['integralRuleUserBody']   = serialize((!in_array($data['integralRuleUserType'], ['allUser']) ? $data[$data['integralRuleUserType']] : []));
                $data['integralRuleGoodsBody']  = serialize((!in_array($data['integralRuleGoodsType'], ['allGoods']) ? $data[$data['integralRuleGoodsType']] : []));

                $integralRuleInfo = $this->integralRuleManager->addIntegralRule($data);
                $this->createConfig()->createIntegralRule();

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('积分规则 %s 添加成功!'), $integralRuleInfo->getIntegralRuleTitle()), $this->translator->translate('积分'));

                return $this->redirect()->toRoute('user-integral', ['action' => 'integralRule']);
            }
        }

        return ['form' => $form, 'classList' => $classList, 'brandList' => $brandList, 'currencySymbol'=> Common::configValue('default', 'currency')['symbol']];
    }

    /**
     * 编辑积分规则
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function editIntegralRuleAction()
    {
        $integralRuleId     = (int) $this->params()->fromRoute('id', -1);
        $integralRuleInfo   = $this->entityManager->getRepository(IntegralRule::class)->findOneBy(['integralRuleId' => $integralRuleId]);
        if($integralRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该积分规则不存在!'));
            return $this->redirect()->toRoute('user-integral', ['action' => 'integralRule']);
        }

        //商品分类
        $goodsClass = $this->entityManager->getRepository(GoodsClass::class)->findBy([], ['classTopId' => 'ASC', 'classSort' => 'ASC']);
        $classList  = Common::classOptions($goodsClass);
        //商品品牌
        $brandList  = $this->goodsPlugin()->goodsBrandOptions('', false);

        $form = new IntegralRuleForm();
        $form->get('integralRuleType')->setValueOptions(['goodsBuy' => $this->translator->translate('商品购买'), 'userRegister' => $this->translator->translate('会员注册')]);
        $form->get('integralTypeId')->setValueOptions(Common::integralType($this->translator));
        $form->get('integralRuleUserType')->setValueOptions(['allUser' => $this->translator->translate('所有客户'), 'userGroup' => $this->translator->translate('客户分组')]);
        $form->get('userGroup')->setValueOptions($this->userPlugin()->userGroupOptions('', false));
        $form->get('integralRuleGoodsType')->setValueOptions(['allGoods' => $this->translator->translate('所有商品'), 'goodsClass' => $this->translator->translate('商品分类'), 'goodsBrand' => $this->translator->translate('商品品牌')]);
        $form->get('goodsBrand')->setValueOptions($brandList);
        $form->get('goodsClass')->setValueOptions($this->goodsPlugin()->classValueArray($goodsClass));

        if($this->getRequest()->isPost()) {
            $postData = $this->params()->fromPost();
            $form->setData($postData);
            if ($form->isValid()) {
                $data = $form->getData();

                if(!empty($data['integralRuleStartTime']))  $data['integralRuleStartTime']  = strtotime($data['integralRuleStartTime']);
                if(!empty($data['integralRuleEndTime']))    $data['integralRuleEndTime']    = strtotime($data['integralRuleEndTime']);
                $data['integralRuleBody']       = serialize((!in_array($data['integralRuleType'], ['userRegister']) ? $postData[$data['integralRuleType']] : []));
                $data['integralRuleUserBody']   = serialize((!in_array($data['integralRuleUserType'], ['allUser']) ? $data[$data['integralRuleUserType']] : []));
                $data['integralRuleGoodsBody']  = serialize((!in_array($data['integralRuleGoodsType'], ['allGoods']) ? $data[$data['integralRuleGoodsType']] : []));

                $integralRuleInfo = $this->integralRuleManager->editIntegralRule($data, $integralRuleInfo);
                $this->createConfig()->createIntegralRule();

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('积分规则 %s 编辑成功!'), $integralRuleInfo->getIntegralRuleTitle()), $this->translator->translate('积分'));

                return $this->redirect()->toRoute('user-integral', ['action' => 'editIntegralRule', 'id' => $integralRuleId]);
            }
        } else {
            $ruleArray = $integralRuleInfo->valuesArray();
            $ruleArray['integralRuleStartTime'] = $ruleArray['integralRuleStartTime'] > 0 ? date("Y-m-d", $ruleArray['integralRuleStartTime']) : '';
            $ruleArray['integralRuleEndTime']   = $ruleArray['integralRuleEndTime'] > 0 ? date("Y-m-d", $ruleArray['integralRuleEndTime']) : '';
            $form->setData($ruleArray);
            if($ruleArray['integralRuleUserType'] == 'userGroup') {
                $form->setData(['userGroup' => unserialize($ruleArray['integralRuleUserBody'])]);
            }
        }

        return ['form' => $form, 'integralRuleInfo' => $integralRuleInfo, 'classList' => $classList, 'brandList' => $brandList, 'currencySymbol'=> Common::configValue('default', 'currency')['symbol']];
    }

    /**
     *
     * @return mixed
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function deleteIntegralRuleAction()
    {
        if(!$this->adminCommon()->validatorCsrf()) return $this->adminCommon()->toReferer();

        $integralRuleId     = (int) $this->params()->fromRoute('id', -1);
        $integralRuleInfo   = $this->entityManager->getRepository(IntegralRule::class)->findOneBy(['integralRuleId' => $integralRuleId]);
        if($integralRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该积分规则不存在!'));
            return $this->adminCommon()->toReferer();
        }

        $this->integralRuleManager->deleteIntegralRule($integralRuleInfo);
        $this->createConfig()->createIntegralRule();

        $this->adminCommon()->addOperLog(sprintf($this->translator->translate('积分规则 %s 删除成功!'), $integralRuleInfo->getIntegralRuleTitle()), $this->translator->translate('积分'));

        return $this->adminCommon()->toReferer();
    }

    /**
     * 积分记录
     * @return array
     */
    public function integralLogAction()
    {
        $page = (int) $this->params()->fromQuery('page', 1);

        $search = [];
        $searchForm = new SearchIntegralLogForm();
        $searchForm->get('integral_type_id')->setValueOptions(Common::integralType($this->translator));
        if($this->getRequest()->isGet()) {
            $data = $this->params()->fromQuery();
            $searchForm->setData($data);
            if($searchForm->isValid()) $search = $searchForm->getData();
        }

        $query  = $this->entityManager->getRepository(IntegralLog::class)->findUserIntegralLog($search);
        $paginator  = $this->adminCommon()->shopPaginator($query, $page);

        return ['integralLogList' => $paginator, 'searchForm' => $searchForm];
    }

    /**
     * 客户积分调整
     * @return array|\Laminas\Http\Response
     */
    public function editUserIntegralAction()
    {
        $userId     = (int) $this->params()->fromRoute('id', -1);
        $userInfo   = $this->entityManager->getRepository(User::class)->findOneByUserId($userId);
        if($userInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该用户不存在!'));
            return $this->redirect()->toRoute('user');
        }

        $queryData = $this->params()->fromQuery();

        $form = new EditUserIntegralForm($userInfo);
        $form->get('changeIntegral1')->setValueOptions(Common::changeType($this->translator));
        $form->get('changeIntegral2')->setValueOptions(Common::changeType($this->translator));

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();

                $this->entityManager->beginTransaction();
                try {
                    $updateIntegral = [];
                    if($data['changeIntegral1Num'] > 0) {//消费积分
                        $changeIntegralNum1 = $data['changeIntegral1'].$data['changeIntegral1Num'];
                        $integralNum = $userInfo->getIntegralType1Num() + $changeIntegralNum1;
                        $this->integralLogManager->addIntegralLog([
                            'userId'            => $userId,
                            'userName'          => $userInfo->getUserName(),
                            'integralLogInfo'   => $data['integralLogInfo'],
                            'changeIntegralNum' => $changeIntegralNum1,
                            'integralNum'       => $integralNum,
                            'integralTypeId'    => 1,
                            'integralLogTime'   => time(),
                            'adminId'           => $this->adminCommon()->admin('admin_id'),
                            'adminName'         => $this->adminCommon()->admin('admin_name')
                        ]);
                        $updateIntegral['integralType1Num'] = $integralNum;
                        $this->adminCommon()->addOperLog($this->translator->translate('管理员调整消费积分') . ' ' . $this->translator->translate('被调整客户:').$userInfo->getUserName() . ',' . $this->translator->translate('调整值:').$changeIntegralNum1, $this->translator->translate('积分'), false);
                    }
                    if($data['changeIntegral2Num'] > 0) {//等级积分
                        $changeIntegralNum2 = $data['changeIntegral2'].$data['changeIntegral2Num'];
                        $integralNum = $userInfo->getIntegralType2Num() + $changeIntegralNum2;
                        $this->integralLogManager->addIntegralLog([
                            'userId'            => $userId,
                            'userName'          => $userInfo->getUserName(),
                            'integralLogInfo'   => $data['integralLogInfo'],
                            'changeIntegralNum' => $changeIntegralNum2,
                            'integralNum'       => $integralNum,
                            'integralTypeId'    => 2,
                            'integralLogTime'   => time(),
                            'adminId'           => $this->adminCommon()->admin('admin_id'),
                            'adminName'         => $this->adminCommon()->admin('admin_name')
                        ]);
                        $updateIntegral['integralType2Num'] = $integralNum;
                        $this->adminCommon()->addOperLog($this->translator->translate('管理员调整等级积分') . ' ' . $this->translator->translate('被调整客户:').$userInfo->getUserName() . ',' . $this->translator->translate('调整值:').$changeIntegralNum2, $this->translator->translate('积分'), false);
                    }
                    //更新积分
                    if(!empty($updateIntegral)) $this->userManager->updateUserIntegral($updateIntegral, $userInfo);

                    $this->entityManager->commit();

                    $this->flashMessenger()->addSuccessMessage($userInfo->getUserName() . ' ' . $this->translator->translate('积分调整完成'));
                } catch (\Exception $e) {
                    $this->entityManager->rollback();
                    $this->flashMessenger()->addWarningMessage($userInfo->getUserName() . ' ' . $this->translator->translate('积分调整失败'));
                }

                return $this->redirect()->toRoute('user', [], ['query' => $queryData]);
            }
        } else $form->setData(['userName' => $userInfo->getUserName()]);

        return ['userInfo' => $userInfo, 'form' => $form, 'queryData' => $queryData];
    }
}